from symbol_table import SymbolTable
import re

class BlockTableEntry():
	def __init__(self,name,father):
		self.st = SymbolTable(name)
		self.father = father
		self.name = name

	def insert(self,lexema,jsType=None):
		return self.st.insert(lexema,jsType)
	
	def insertTemporal(self,lexeme,jsType):
		return self.st.insertTemporal(lexeme,jsType)

	def getName(self):
		return self.name

	def getSymbolTable(self):
		return self.st

	def setSymbolTable(self,st):
		self.st = st
		return self.st

	def getFather(self):
		return self.father

	def getFormerSymbolTable(self):
		entry = self.currentBt.getFather()
		return entry.getSymbolTable()

	def getPos(self,lexeme):
		pos = self.st.getPos(lexeme)
		if pos == None:
			if self.father != None:
				return self.father.getPos(lexeme)
			return None
		else:
			return pos


	def getPost(self,lexeme):
		post = self.st.getPost(lexeme)
		if post == None:
			if self.father != None:
				return self.father.getPost(lexeme)
			return None
		else:
			return post

	def isDefined(self,lexeme):
		pos = self.getPos(lexeme)
		return pos != None

	def getType(self,lexeme):
		jstype = self.st.getType(lexeme)

		if jstype == None:
			if self.father != None:
				return self.father.getType(lexeme)
			return None
		else:
			return jstype

	def setType(self,lexeme,jstype):
		type = self.st.setType(lexeme,jstype)
		if type == None:
			if self.father != None:
				return self.father.setType(lexeme,jstype)
			return None
		else:
			return type

	def setDepth(self,depth):
		self.st.setDepth(depth)

	def getDepth(self):
		return self.st.getDepth()

	
	def setLocation(self,lexeme,location):

		attRe = re.compile("(.+)(\.)(.*)")
		attReRes = attRe.search(lexeme)

		if attReRes != None and "this" not in lexeme:
			#lexeme is an object
			objLexeme = attReRes.group(1)	

			pos = self.st.getPos(objLexeme)

			if pos == None:
				if self.father != None:
					return self.father.getLocation(lexeme)
				return None
			else:
				#self.st.getType(objLexeme).getSymbolTable().printAll()
				return self.st.getType(objLexeme).getSymbolTable().setLocation(lexeme,location)
		else:
			locationSt = self.st.getLocation(lexeme)
			if locationSt == None:
				if self.father != None:
					return self.father.setLocation(lexeme,location)
				return None
			else:

				return self.st.setLocation(lexeme,location)

	
	def getLocation(self,lexeme):

		attRe = re.compile("(.+)(\.)(.*)")
		attReRes = attRe.search(lexeme)

		if attReRes != None and "this" not in lexeme:
			#lexeme is an object
			objLexeme = attReRes.group(1)	

			pos = self.st.getPos(objLexeme)

			if pos == None:
				if self.father != None:
					return self.father.getLocation(lexeme)
				return None
			else:
				#self.st.getType(objLexeme).getSymbolTable().printAll()
				return self.st.getType(objLexeme).getSymbolTable().getLocation(lexeme)
		else:

			location = self.st.getLocation(lexeme)

			if location == None:
				if self.father != None:
					return self.father.getLocation(lexeme)
				return None
			else:
				return location

	def setLive(self,lexeme):
		live = self.st.setLive(lexeme)
		if live == None:
			if self.father != None:
				return self.father.setLive(lexeme)
			return None
		else:
			return live

	def setNoLive(self,lexeme):
		live = self.st.setNoLive(lexeme)
		if live == None:
			if self.father != None:
				return self.father.setNoLive(lexeme)
			return None
		else:
			return live

	def setNextUse(self,lexeme,index):
		nextUse = self.st.setNextUse(lexeme,index)
		if nextUse == None:
			if self.father != None:
				return self.father.setNextUse(lexeme,index)
			return None
		else:
			return nextUse
	
	def setNoNextUse(self,lexeme):
		nextUse = self.st.setNoNextUse(lexeme)
		if nextUse == None:
			if self.father != None:
				return self.father.setNoNextUse(lexeme)
			return None
		else:
			return nextUse

	def printAll(self):
		print "------------------"
		if self.father != None:
			fatherName = self.father.getName()
		else:
			fatherName = ""
		print "Block : Name:%s Father:%s"%(self.name,fatherName)
		print "Symbol Table: " + self.getName()
		print "Depth:%d"%self.st.getDepth()
		print "------------------"
		self.st.printAll()

